//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//////////////////////////////////////////////////////////////////////

#ifndef __CONFIG_MANAGER__
#define __CONFIG_MANAGER__

#include "definitions.h"
#include "enums.h"

#include <string>

extern "C"
{
	#include <lua.h>
	#include <lauxlib.h>
	#include <lualib.h>
}

class ConfigManager
{
	public:
		ConfigManager();
		virtual ~ConfigManager() {}

		enum string_config_t 
		{
			DUMMY_STR = 0,
			CONFIG_FILE,
			DATA_DIRECTORY,
			MAP_FILE,
			HOUSE_RENT_PERIOD,
			LOGIN_MSG,
			SERVER_NAME,
			OWNER_NAME,
			OWNER_EMAIL,
			URL,
			LOCATION,
			IP,
			MOTD,
			PASSWORD_TYPE_STR,
			PASSWORD_SALT,
			WORLD_TYPE,
			SQL_HOST,
			SQL_USER,
			SQL_PASS,
			SQL_DB,
			SQLITE_DB,
			SQL_TYPE,
			MAP_STORAGE_TYPE,
			DEATH_MSG,
			DEFAULT_PRIORITY,
			OTSERV_VERSION_STRING,
			LAST_STRING_CONFIG /* this must be the last one */
		};

    	enum integer_config_t
		{
			LOGIN_TRIES = 0,
			GAME_PORT,
			ADMIN_PORT,
			LOGIN_PORT,
			STATUS_PORT,
			RETRY_TIMEOUT,
			LOGIN_TIMEOUT,
			MAX_PLAYERS,
			EXHAUSTED,
			EXHAUSTED_ADD,
			COMBAT_EXHAUSTED,
			HEAL_EXHAUSTED,
			HUNTING_KILL_DURATION,
			IN_FIGHT_DURATION,
			FIELD_OWNERSHIP_DURATION,
			MIN_ACTIONTIME,
			MIN_ACTIONEXTIME,
			DEFAULT_DESPAWNRANGE,
			DEFAULT_DESPAWNRADIUS,
			PARTY_MEMBER_EXP_BONUS,
			RATE_STAMINA_LOSS,
			RATE_STAMINA_GAIN,
			SLOW_RATE_STAMINA_GAIN,
			MAX_MESSAGEBUFFER,
			PASSWORD_TYPE,
			SQL_PORT,
			STATUSQUERY_TIMEOUT,
			UNJUST_SKULL_DURATION,
			KILLS_PER_DAY_RED_SKULL,
			KILLS_PER_WEEK_RED_SKULL,
			KILLS_PER_MONTH_RED_SKULL,
			KILLS_PER_DAY_BLACK_SKULL,
			KILLS_PER_WEEK_BLACK_SKULL,
			KILLS_PER_MONTH_BLACK_SKULL,
			RED_SKULL_DURATION,
			BLACK_SKULL_DURATION,
			LOGIN_ATTACK_DELAY,
			STAMINA_EXTRA_EXPERIENCE_DURATION,
			STAIRHOP_EXHAUSTED,
			IDLE_TIME,
			IDLE_TIME_WARNING,
			HOUSE_LEVEL,
			HOUSE_TILE_PRICE,
			NOTATIONS_TO_BAN,
			WARNINGS_TO_FINALBAN,
			WARNINGS_TO_DELETION,
			BAN_LENGTH,
			FINALBAN_LENGTH,
			IPBANISHMENT_LENGTH,
			DEATH_ASSIST_COUNT,
			NPC_MAX_NONESTACKABLE_SELL_AMOUNT,
			FIST_STRENGTH,
			GUILD_WAR_FEE,
			MIN_PVP_LEVEL,
			HEIGHT_MINIMUM_FOR_IDLE,
			CRITICAL_DAMAGE_CHANCE,
			SERVERSAVE_H,
			MAX_PLAYER_SUMMON,
			PUSH_INTERVAL,
			RATE_EXPERIENCE_PVP,
			RATE_EXPERIENCE,
			RATE_SKILL,
			RATE_LOOT,
			RATE_MAGIC,
			RATE_SPAWN,
			TRADE_ITEMS_LIMIT,
			BLACK_SKULL_DEATH_HEALTH,
			BLACK_SKULL_DEATH_MANA,
			AUTOSAVE_TIME,
			OTSERV_MIN_VERSION,
			OTSERV_MAX_VERSION,
			LAST_INTEGER_CONFIG /* this must be the last one */
		};

		enum float_config_t 
		{
			STAMINA_EXTRA_EXPERIENCE_RATE,
			LAST_FLOAT_CONFIG /* this must be the last one */
		};
	
		enum bool_config_t 
		{
    	    USE_HOTKEYS,
    	    LAST_HIT_PZBLOCK_ONLY,
        	DEFENSIVE_PZ_LOCK,
        	DISPLAY_CRITICAL_DAMAGE,
        	ALLOW_CHANGE_OUTFIT,
        	OUTFIT_DAMAGE,
        	ENABLE_CAP,
        	ALLOW_CLONES,
        	ONE_PLATER_ACCOUNT,
        	RATES_FOR_PLAYER_KILLING,
        	STAMINA_EXTRA_EXPERIENCE_ONLYPREM,
        	BROADCAST_BANISHMENTS,
        	ALLOW_GAMEMASTER_MULTICLIENT,
        	ADDONS_ONLY_FOR_PREMIUM,
        	MW_DISAPPEAR_ON_WALK,
			#ifdef __MIN_PVP_LEVEL_APPLIES_TO_SUMMONS__
			MIN_PVP_LEVEL_APPLIES_TO_SUMMONS,
			#endif
			MONSTER_SPAWN_WALKBACK,
			REMOVE_AMMUNITION,
			REMOVE_RUNE_CHARGES,
			REMOVE_WEAPON_CHARGES,
			DISTANCE_WEAPON_INTERRUPT_SWING,
			WANDS_INTERRUPT_SWING,
			SHOW_NEW_SKILL_LEVEL,
			SHOW_HEALING,
			SHOW_MANA_DAMAGE,
			ORANGE_SPELL_TEXT,
			SHOW_DEATH_WINDOW,
			CAN_ATTACK_INVISIBLE,
			CAN_PASS_THROUGH,
			EXPERIENCE_STAGES,
			ENABLE_MOUNTS,
			ENABLE_COOLDOWN,
			USE_BALANCE_HOUSE_PAYING,
			PREMIUM_ONLY_BEDS,
			SHOW_HOUSE_PRICES,
			HOUSE_ONLY_PREMIUM,
			SERVERSAVE_ENABLED,
			SHUTDOWN_AT_SERVERSAVE,
			CLEAN_MAP_AT_SERVERSAVE,
			FOLLOW_SUMMONS_PLAYERS,
			SHOW_MONSTER_HEALING,
			FREE_PREMIUM,
			AUTOSAVE_ENABLED,
			LAST_BOOL_CONFIG /* this must be the last one */
		};


		bool loadFile(const std::string& _filename);
		bool reload();

		void getConfigValue(const std::string& key, lua_State* _L);
		const std::string& getString(uint32_t _what) const;
		double getDouble(uint32_t _what) const;
		int64_t getNumber(uint32_t _what) const;
		bool setNumber(uint32_t _what, int64_t _value);
		bool setString(uint32_t _what, const std::string& _value);
		bool getBool(uint32_t _what) const;

	private:
		static void moveValue(lua_State* fromL, lua_State* toL);
		std::string getGlobalString(lua_State* _L, const std::string& _identifier, const std::string& _default="");
		int64_t getGlobalNumber(lua_State* _L, const std::string& _identifier, int64_t _default=0);
		double getGlobalFloat(lua_State* _L, const std::string& _identifier, double _default=0.0);
		bool getGlobalBool(lua_State* _L, const std::string& _identifier, bool _default=false);

		lua_State* L;
		bool m_isLoaded;
		std::string m_confString[LAST_STRING_CONFIG];
		int64_t m_confInteger[LAST_INTEGER_CONFIG];
		double m_confFloat[LAST_FLOAT_CONFIG];
		bool m_confBool[LAST_BOOL_CONFIG];
};
#endif
